package vip.zhenzicheng.websocket.netty_socketio.config;

import com.corundumstudio.socketio.SocketConfig;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Netty SocketIO 配置类
 *
 * @author zhenzicheng
 * @date 2023-04-14 15:35
 */
@Configuration
public class SocketIoConfig implements InitializingBean {

    @Bean
    public SocketIOServer socketIOServer() {
        SocketConfig socketConfig = new SocketConfig();
        socketConfig.setReuseAddress(true);
        socketConfig.setTcpNoDelay(true);
        socketConfig.setSoLinger(0);

        com.corundumstudio.socketio.Configuration configuration = new com.corundumstudio.socketio.Configuration();
        configuration.setSocketConfig(socketConfig);
        // TODO 2023-04-14 可以考虑放在配置文件
        configuration.setHostname("localhost");
        configuration.setPort(9000);
        // 允许跨域
        configuration.setOrigin("*");
        // socket 连接数（只监听一个端口，设置线程组为1即可）
        configuration.setBossThreads(1);
        configuration.setWorkerThreads(100);
        configuration.setAllowCustomRequests(true);
        // 协议升级超时时间（ms），默认10s，HTTP 握手升级为 ws 协议的超时时间
        configuration.setUpgradeTimeout(10000);
        // Ping 消息超时时间（ms），默认60s，超时没有接收到心跳会发送超时事件
        configuration.setPingTimeout(60000);
        // Ping 消息间隔时间（ms），默认25s
        configuration.setPingInterval(25000);


        // 鉴权管理 --> SpringBoot OAuth2.0 封装登录、刷新令牌接口
        // config.setAuthorizationListener(new AuthorizationListener() {
        //     @Override public boolean isAuthorized(HandshakeData data) {
        //         String accessToken = data.getSingleUrlParam(OAuth2AccessToken.ACCESS_TOKEN);
        //         if (StringUtils.isEmpty(accessToken)) {
        //             return false;
        //         }
        //         OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(accessToken);
        //         return !ObjectUtils.isEmpty(oAuth2AccessToken);
        //     }
        // });
        return new SocketIOServer(configuration);
    }

    /**
     * 用于扫描 netty-socketio 注解，例如：@OnConnect、@OnEvent
     */
    @Bean
    public SpringAnnotationScanner springAnnotationScanner() {
        return new SpringAnnotationScanner(socketIOServer());
    }

    @Override
    public void afterPropertiesSet() {
        // 初始化后直接启动
        socketIOServer().start();
    }
}
